package com.eureka.bclass.util;

import com.alibaba.fastjson.JSONObject;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.SimpleBookmark;
import org.apache.commons.lang3.StringUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @Description: pdf工具类
 * @Author: lixing
 * @Date: 2021/7/29 15:37
 */
public class PdfUtil {
    public static void main(String[] args) throws IOException {
        String pdfUrl = "https://etigertest.oss-cn-hangzhou.aliyuncs.com/2021/07/29/a7c1bf4cdd42479e9f7198778e2f42a3.pdf";
        List<InputStream> imageInputStreamList = getImageFromPdf(pdfUrl);
        System.out.println(imageInputStreamList.size());
    }

    /**
     * @Description 获取目录以及对应的页码
     * @Author lixing
     * @Date 2021/8/9 14:40
     */
    private static void showBookmark(HashMap<String, Object> bookmark, List<JSONObject> pdfBookmarkInfoList) {
        String title = null != bookmark.get("Title") ? bookmark.get("Title").toString() : "标题不存在";
        int pageNum = -1;
        String page = null != bookmark.get("Page") ? bookmark.get("Page").toString() : null;
        if (!StringUtils.isEmpty(page)) {
            String[] pageArray = page.split(" ");
            pageNum = pageArray.length > 0 ? Integer.parseInt(pageArray[0]) : -1;
        }
        JSONObject pdfBookmarkInfo = new JSONObject();
        pdfBookmarkInfo.put("title", title);
        pdfBookmarkInfo.put("pageNum", pageNum);
        //log.info("获取标题和标题页码-- " + JSONObject.toJSONString(pdfBookmarkInfo));
        pdfBookmarkInfoList.add(pdfBookmarkInfo);
        //
        @SuppressWarnings("unchecked")
        ArrayList<HashMap<String, Object>> kids = (ArrayList<HashMap<String, Object>>) bookmark.get("Kids");
        if (null != kids) {
            for (HashMap<String, Object> kid : kids) {
                showBookmark(kid, pdfBookmarkInfoList);
            }
        }
    }

    /**
     * @Description 获取页码
     * @Author lixing
     * @Date 2021/8/9 14:37
     */
    public static void getPageNumbers(HashMap<String, Object> bookmark) {
        if (bookmark == null) {
            return;
        }
        if ("GoTo".equals(bookmark.get("Action"))) {
            String page = (String) bookmark.get("Page");
            if (page != null) {
                page = page.trim();
                int idx = page.indexOf(' ');
                int pageNum;
                if (idx < 0) {
                    pageNum = Integer.parseInt(page);
                    //System.out.println("pageNum :" + pageNum);
                } else {
                    pageNum = Integer.parseInt(page.substring(0, idx));
                    //System.out.println("pageNum:" + pageNum);
                }
            }
            @SuppressWarnings("unchecked")
            ArrayList<HashMap<String, Object>> kids = (ArrayList<HashMap<String, Object>>) bookmark.get("Kids");
            if (kids == null) {
                return;
            }
            for (HashMap<String, Object> kid : kids) {
                getPageNumbers(kid);
            }
        }
    }

    /**
     * @Description 获取pdf的目录以及其页码信息
     * @Author lixing
     * @Date 2021/8/2 14:15
     * @Param [pdfUrl 外链地址]
     * @return java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
     */
    public static List<JSONObject> getPdfBookmarkInfo(String pdfUrl) {
        List<JSONObject> pdfBookmarkInfoList = new ArrayList<>();
        PdfReader reader = null;
        try {
            reader = new PdfReader(new URL(pdfUrl));
            List<HashMap<String, Object>> pdfmlList = SimpleBookmark.getBookmark(reader);
            if (null != pdfmlList && !pdfmlList.isEmpty()) {
                for (HashMap<String, Object> stringObjectHashMap : pdfmlList) {
                    showBookmark(stringObjectHashMap, pdfBookmarkInfoList);
                }
            } else {
                LoggerUtil.info(MessageFormat.format("{0} 没有目录", pdfUrl));
            }
        } catch (IOException e) {
            LoggerUtil.error(MessageFormat.format("读取pdf出错：{0}", e.getMessage()));
            return new ArrayList<>();
        } finally {
            if (null != reader) {
                reader.close();
            }
        }
        return pdfBookmarkInfoList;
    }

    /**
     * @Description 获取pdf指定页面的文本内容
     * @Author lixing
     * @Date 2021/8/2 13:59
     * @Param [pdfUrl 外链地址, startPage 开始页页码, endPage 结束页页码]
     * @return java.util.List<java.util.Map<java.lang.String,java.lang.String>>
     */
    public static List<String> getPdfTextByPageNum(String pdfUrl, int startPage, int endPage) {
        // 返回结果
        List<String> pdfText = new ArrayList<>(endPage - startPage + 1);
        //
        //        PDDocument pdDocument = null;
        //        PDFTextStripperByArea pdfTextStripperByArea;
        //        PDFTextStripper pdfTextStripper;
        //        try {
        //            InputStream pdfInputStream = FileUtil.downFileByHttpUrl(pdfUrl);
        //            // TODO 本地测试使用
        //            //            pdfInputStream = new FileInputStream(new File("D:\\demo2.pdf"));
        //            pdDocument = PDDocument.load(pdfInputStream);
        //            // 读取页面内容
        //            for (int i = startPage; i <= endPage; i++) {
        //                pdfTextStripperByArea = new PDFTextStripperByArea();
        //                pdfTextStripperByArea.setSortByPosition(true);
        //                pdfTextStripper = new PDFTextStripper();
        //                pdfTextStripper.setStartPage(startPage);
        //                pdfTextStripper.setEndPage(endPage);
        //                String text = pdfTextStripper.getText(pdDocument);
        //                //
        //                pdfText.add(text);
        //            }
        //        } catch (IOException e) {
        //            e.printStackTrace();
        //        } finally {
        //            if (null != pdDocument) {
        //                try {
        //                    pdDocument.close();
        //                } catch (IOException e) {
        //                    e.printStackTrace();
        //                }
        //            }
        //        }
        return pdfText;
    }

    /**
     * @return org.springframework.web.multipart.MultipartFile[]
     * @Description 获取pdf文件中的所有图片并返回
     * @Author lixing
     * @Date 2021/7/29 15:38
     * @Param [pdfUrl 在线地址]
     */
    public static List<InputStream> getImageFromPdf(String pdfUrl) throws IOException {
        List<InputStream> imageInputStreamList = new ArrayList<>();
        PDDocument document = null;
        // PDF文件流
        InputStream inputStream = null;
        try {
            // PDF文件流
            inputStream = FileUtil.downFileByHttpUrl(pdfUrl);
            // PDF文件对象
            document = PDDocument.load(inputStream);
            PDFRenderer pdfRenderer = new PDFRenderer(document);
            // PDF页码
            int pageNumber = document.getNumberOfPages();
            for (int i = 0; i < pageNumber; i++) {
                // 以 150 dpi 读取存入 BufferedImage 对象
                BufferedImage bufferedImage = pdfRenderer.renderImageWithDPI(i, 150);
                InputStream imageInputStream = ImageUtil.getInputStreamFromBufferedImage(bufferedImage, "png");
                imageInputStreamList.add(imageInputStream);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != document) {
                document.close();
            }
            if (null != inputStream) {
                inputStream.close();
            }
        }
        return imageInputStreamList;
    }

    /**
     * @return org.springframework.web.multipart.MultipartFile[]
     * @Description 获取pdf文件中的所有图片并返回（多线程）
     * @Author lixing
     * @Date 2021/7/29 15:38
     * @Param [pdfUrl 在线地址]
     */
    // 自定义pdf图片预览的线程对象
//    static class PdfPreviewTask implements Callable<InputStream> {
//        /** 当前页 */
//        private int currentPage;
//        /** PDFRenderer对象 */
//        private PDFRenderer pdfRenderer;
//
//        public PdfPreviewTask(int currentPage, PDFRenderer pdfRenderer) {
//            this.currentPage = currentPage;
//            this.pdfRenderer = pdfRenderer;
//        }
//
//        @Override
//        public InputStream call() {
//            try {
//                // 以 150 dpi 读取存入 BufferedImage 对象
//                BufferedImage bufferedImage = pdfRenderer.renderImageWithDPI(currentPage, 150);
//                // ImageIO.write(image, "jpg", new File(rootFilePath + "/" + fileName + "/" + ( currentPage + 1 ) +".jpg"));
//                InputStream imageInputStream = ImageUtil.getInputStreamFromBufferedImage(bufferedImage, "png");
//                return imageInputStream;
//            } catch (Exception e) {
//                e.printStackTrace();
//                return null;
//            }
//        }
//    }
//    public static List<InputStream> getImageFromPdf(String pdfUrl, ThreadPoolTaskExecutor threadPoolExecutor) throws ExecutionException, InterruptedException, IOException {
//        List<InputStream> imageInputStreamList = new ArrayList<>();
//        List<Future<InputStream>> futureTaskList = new ArrayList<>();
//        // 默认pdf页数为0
//        int pageCount = 0;
//        //
//        PDDocument pdDocument = null;
//        try {
//            pdDocument = PDDocument.load(FileUtil.downFileByHttpUrl(pdfUrl));
//            PDFRenderer pdfRenderer = new PDFRenderer(pdDocument);
//            pageCount = pdDocument.getNumberOfPages();
//            for (int i = 0; i < pageCount; i++) {
//                // threadPoolExecutor (ThreadPoolTaskExecutorConfig.taskExecutorPool;)
//                futureTaskList.add(threadPoolExecutor.submit(new PdfPreviewTask(i, pdfRenderer)));
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//        } finally {
//            boolean flag;
//            for (int i = 0; i < pageCount; i++) {
//                flag = true;
//                while (flag) {
//                    Future<InputStream> inputStreamFuture = futureTaskList.get(i);
//                    if (inputStreamFuture.isDone()) {
//                        imageInputStreamList.add(inputStreamFuture.get());
//                        flag = false;
//                    } else {
//                        try {
//                            Thread.sleep(1000);
//                        } catch (InterruptedException e) {
//                            e.printStackTrace();
//                        }
//                    }
//                }
//            }
//            if (pdDocument != null) {
//                pdDocument.close();
//            }
//        }
//        return imageInputStreamList;
//    }

}
